from django.db import models
from django.conf import settings
from basics import models as basics_models
from Login import models as login_models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericRelation
from utils.models_save import ModelsSave

# Create your models here.

__all__ = [
    "Api",
    "ApiDetail",
]


# 接口表
class Api(models.Model):
    project = models.ForeignKey(basics_models.Project, on_delete=True, verbose_name="所属项目")
    creator = models.ForeignKey(login_models.Account, on_delete=True, verbose_name="创建人")
    sql_detail_body = models.ForeignKey(to=basics_models.SqlDetail, blank=True, null=True, on_delete=models.CASCADE,
                                        related_name="请求体sql", verbose_name='请求体sql')
    sql_detail_assert = models.ForeignKey(to=basics_models.SqlDetail, blank=True, null=True, on_delete=models.CASCADE,
                                          related_name="断言sql", verbose_name='断言sql')
    name = models.CharField(unique=True, max_length=40, verbose_name="接口名称")
    obj_key = models.CharField(max_length=128, unique=True, blank=True, null=True, default=None, verbose_name='步骤key')
    api_type = models.IntegerField(choices=settings.MODELS_CHOICES['api']['api_type'], verbose_name='请求方式')
    url = models.CharField(max_length=200, verbose_name="URL")  # 不包含协议，IP、端口
    steps_data = models.TextField(blank=True, null=True, default=None, verbose_name="步骤数据")
    sample_header = models.TextField(blank=True, null=True, default=None, verbose_name='请求头示例')
    sample_body = models.TextField(blank=True, null=True, default=None, verbose_name='请求体示例')
    sample_response = models.TextField(blank=True, null=True, default=None, verbose_name='响应数据示例')
    header_template = models.TextField(blank=True, null=True, default=None, verbose_name='请求头模板')
    request_sql_template = models.TextField(blank=True, null=True, default=None, verbose_name='请求sql入参模板')
    request_pull_template = models.TextField(blank=True, null=True, default=None, verbose_name='请求出参模板')
    assert_sql_template = models.TextField(blank=True, null=True, default=None, verbose_name='断言sql入参模板')
    assert_pull_template = models.TextField(blank=True, null=True, default=None, verbose_name='断言出参模板')
    header = models.TextField(blank=True, null=True, default=None, verbose_name='请求头')  # 合成请求头
    body = models.FileField(upload_to='Api/body/%Y-%m', blank=True, null=True, verbose_name="请求体")  # 合成请求体
    response = models.FileField(upload_to='Api/response/%Y-%m', blank=True, null=True, default=None,
                                verbose_name='响应数据')
    assert_data = models.FileField(upload_to='Api/assert_data/%Y-%m', blank=True, null=True, default=None,
                                   verbose_name='断言数据')
    result_data = models.FileField(upload_to='Api/result_data/%Y-%m', blank=True, null=True, default=None,
                                   verbose_name='对比结果')
    describe = models.CharField(max_length=200, blank=True, verbose_name="接口描述")
    create_time = models.DateTimeField(blank=True, null=True, verbose_name="创建日期")
    update_time = models.DateTimeField(blank=True, null=True, verbose_name="更新日期")
    results = models.IntegerField(choices=settings.MODELS_CHOICES['results'], default=3,
                                  verbose_name='执行状态')  # 每次用例执行时写入
    show_status = models.BooleanField(default=True, verbose_name='显示正确结果')  # 是否显示正确结果
    status = models.IntegerField(choices=settings.MODELS_CHOICES['common'], verbose_name="状态")

    def save(self, *args, **kwargs):
        old_obj = Api.objects.filter(id=self.id).first()
        rets = ['result_data', 'assert_data', 'response', 'body']
        ModelsSave(old_obj, self, rets).run()  # 删除旧数据
        super(Api, self).save(*args, **kwargs)

    class Meta:
        unique_together = ('api_type', 'url',)
        verbose_name = '接口'
        verbose_name_plural = '接口'

    def __str__(self):
        return self.name


# 接口实现明细表
class ApiDetail(models.Model):
    api = models.ForeignKey('Api', on_delete=True, verbose_name="关联接口表")
    creator = models.ForeignKey(login_models.Account, on_delete=True, verbose_name="创建人")
    title = models.CharField(max_length=200, verbose_name="标题")  # 标题
    obj_key = models.CharField(max_length=128, unique=True, blank=True, null=True, default=None, verbose_name='步骤key')
    describe = models.CharField(max_length=200, blank=True, verbose_name="接口描述")
    sql_detail_body = models.ForeignKey(to=basics_models.SqlDetail, blank=True, null=True, on_delete=True, default=None,
                                        related_name="接口明细请求体sql", verbose_name='请求体sql')  # related_name：反向查询用的
    sql_detail_assert = models.ForeignKey(to=basics_models.SqlDetail, blank=True, null=True, on_delete=True,
                                          default=None,
                                          related_name="接口明细断言sql", verbose_name='断言sql')
    api_type = models.IntegerField(choices=settings.MODELS_CHOICES['api']['api_type'], verbose_name='请求方式')
    url = models.CharField(max_length=200, blank=True, null=True, verbose_name="URL")  # 不包含协议，IP、端口
    steps_data = models.TextField(blank=True, null=True, default=None, verbose_name="步骤数据")
    header_template = models.TextField(blank=True, null=True, default=None, verbose_name='请求头模板')
    header = models.TextField(blank=True, null=True, default=None, verbose_name='请求头')  # 合成请求头
    request_sql_template = models.TextField(blank=True, null=True, default=None, verbose_name='请求sql入参模板')
    request_pull_template = models.TextField(blank=True, null=True, default=None, verbose_name='请求出参模板')
    body = models.FileField(upload_to='ApiDetail/body/%Y-%m', blank=True, null=True, verbose_name="请求体")  # 合成请求体
    assert_sql_template = models.TextField(blank=True, null=True, default=None, verbose_name='断言sql入参模板')
    assert_pull_template = models.TextField(blank=True, null=True, default=None, verbose_name='断言出参模板')
    response = models.FileField(upload_to='ApiDetail/response/%Y-%m', blank=True, null=True, default=None,
                                verbose_name='响应数据')
    assert_data = models.FileField(upload_to='ApiDetail/assert_data/%Y-%m', blank=True, null=True, default=None,
                                   verbose_name='断言数据')
    result_data = models.FileField(upload_to='ApiDetail/result_data/%Y-%m', blank=True, null=True, default=None,
                                   verbose_name='对比结果')
    create_time = models.DateTimeField(blank=True, null=True, verbose_name="创建日期")
    update_time = models.DateTimeField(blank=True, null=True, verbose_name="更新日期")
    results = models.IntegerField(choices=settings.MODELS_CHOICES['results'], default=3,
                                  verbose_name='执行状态')  # 每次用例执行时写入
    show_status = models.BooleanField(default=True, verbose_name='显示正确结果')  # 是否显示正确结果
    status = models.IntegerField(choices=settings.MODELS_CHOICES['common'], verbose_name="状态")

    cases_detail = GenericRelation(to=basics_models.CasesDetail)  # 与用例明细反向查询用，不生成字段

    def save(self, *args, **kwargs):
        old_obj = ApiDetail.objects.filter(id=self.id).first()
        rets = [
            'result_data',
            'assert_data',
            'response',
            'body']
        ModelsSave(old_obj, self, rets).run()  # 删除旧数据
        super(ApiDetail, self).save(*args, **kwargs)

    class Meta:
        verbose_name = '接口明细表'
        verbose_name_plural = '接口明细表'

    def __str__(self):
        return self.title
